/**
* <copyright>
* Copyright (c) 2010-2014 Henshin developers. All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
* </copyright>
*/
package org.eclipse.emf.henshin.model.impl;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EFactory;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.henshin.model.Action;
import org.eclipse.emf.henshin.model.Attribute;
import org.eclipse.emf.henshin.model.Graph;
import org.eclipse.emf.henshin.model.GraphElement;
import org.eclipse.emf.henshin.model.HenshinPackage;
import org.eclipse.emf.henshin.model.Node;
import org.eclipse.emf.henshin.model.actions.ActionElementFinder;
import org.eclipse.emf.henshin.model.actions.AttributeActionHelper;
/**
* <!-- begin-user-doc -->
* An implementation of the model object '<em><b>Attribute</b></em>'.
* <!-- end-user-doc -->
* <p>
* The following features are implemented:
* <ul>
* <li>{@link org.eclipse.emf.henshin.model.impl.AttributeImpl#getAction <em>Action</em>}</li>
* <li>{@link org.eclipse.emf.henshin.model.impl.AttributeImpl#getType <em>Type</em>}</li>
* <li>{@link org.eclipse.emf.henshin.model.impl.AttributeImpl#getValue <em>Value</em>}</li>
* <li>{@link org.eclipse.emf.henshin.model.impl.AttributeImpl#getNode <em>Node</em>}</li>
* <li>{@link org.eclipse.emf.henshin.model.impl.AttributeImpl#getConstant <em>Constant</em>}</li>
* <li>{@link org.eclipse.emf.henshin.model.impl.AttributeImpl#isNull <em>Null</em>}</li>
* </ul>
* </p>
*
* @generated
*/
public class AttributeImpl extends ModelElementImpl implements Attribute {
/**
* The default value of the '{@link #getAction() <em>Action</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getAction()
* @generated
* @ordered
*/
protected static final Action ACTION_EDEFAULT = null;
/**
* An adapter that automatically updates the derived fields {@link #constant} and {@link #null_}.
* @generated NOT
*/
private Adapter derivedFieldsUpdater = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
int featureID = msg.getFeatureID(Attribute.class);
if (featureID==HenshinPackage.ATTRIBUTE__TYPE || featureID==HenshinPackage.ATTRIBUTE__VALUE) {
updateDerivedFields();
}
}
};
/**
* The cached value of the '{@link #getType() <em>Type</em>}' reference.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getType()
* @generated
* @ordered
*/
protected EAttribute type;
/**
* The default value of the '{@link #getValue() <em>Value</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getValue()
* @generated
* @ordered
*/
protected static final String VALUE_EDEFAULT = null;
/**
* The cached value of the '{@link #getValue() <em>Value</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getValue()
* @generated
* @ordered
*/
protected String value = VALUE_EDEFAULT;
/**
* The default value of the '{@link #getConstant() <em>Constant</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getConstant()
* @generated NOT
* @ordered
*/
protected static final Object CONSTANT_EDEFAULT = null;
/**
* The cached value of the '{@link #getConstant() <em>Constant</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getConstant()
* @generated
* @ordered
*/
protected Object constant = CONSTANT_EDEFAULT;
/**
* The default value of the '{@link #isNull() <em>Null</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #isNull()
* @generated
* @ordered
*/
protected static final boolean NULL_EDEFAULT = false;
/**
* The cached value of the '{@link #isNull() <em>Null</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #isNull()
* @generated
* @ordered
*/
protected boolean null_ = NULL_EDEFAULT;
/**
* <!-- begin-user-doc -->
* Default and only constructor.
* <!-- end-user-doc -->
* @generated NOT
*/
protected AttributeImpl() {
// Add the constant updater to the adapters list:
eAdapters().add(derivedFieldsUpdater);
}
/**
* Update the derived {@link #constant} field of this attribute.
* @generated NOT
*/
protected void updateDerivedFields() {
// Reset constant:
constant = null;
// Supposed to be null?
if (isNull(value)) {
null_ = true;
return;
}
// Otherwise it is not null:
null_ = false;
// We need the value and the type:
if (value==null || type==null) {
return;
}
// Need to resolve the data type first?
if (type.getEType()==null) {
EcoreUtil.resolveAll(this);
}
// Package and factory must be known:
if (type.getEType()==null ||
type.getEType().getEPackage()==null ||
type.getEType().getEPackage().getEFactoryInstance()==null) {
return;
}
// Get a trimmed version of the value:
String v = value.trim();
// Multiple values?
if (type.isMany()) {
if (v.startsWith("[") && v.endsWith("]")) {
v = v.substring(1, v.length()-1);
EList<Object> list = new BasicEList<Object>();
for (String e : v.split(",")) {
if (isNull(e)) {
list.add(null);
} else {
Object c = getConstant(e, type);
if (c!=null) {
list.add(c);
} else {
list = null;
break;
}
}
}
constant = list;
}
} else {
constant = getConstant(v, type);
}
}
/**
* Check whether a string value is "null".
* @param value String value.
* @return <code>true</code> if it is null.
*/
private static boolean isNull(String value) {
return (value!=null) && (value.trim().equalsIgnoreCase("null"));
}
/**
* Try to cast a string value into a constant.
* @param value String value.
* @param type Attribute type.
* @return The constant or <code>null</code>.
*/
private static Object getConstant(String value, EAttribute type) {
// Enum?
if (type.getEType() instanceof EEnum) {
try {
return ((EEnum) type.getEType()).getEEnumLiteral(value);
} catch (Throwable t) {}
}
// Special treatment for strings:
if (type.getEType().getInstanceClass()==String.class) {
String v = value.trim();
if (v.startsWith("\"") && v.endsWith("\"")) { // double quotes
v = v.substring(1, v.length()-1);
if (v.indexOf("\"")<0) {
return v;
}
}
if (v.startsWith("'") && v.endsWith("'")) { // single quotes
v = v.substring(1, v.length()-1);
if (v.indexOf("'")<0) {
return v;
}
}
return null;
}
// Last chance: try to load it using the factory:
try {
EFactory factory = type.getEType().getEPackage().getEFactoryInstance();
return factory.createFromString(type.getEAttributeType(), value);
} catch (Throwable t) {}
// Seems not to be a constant:
return null;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
protected EClass eStaticClass() {
return HenshinPackage.Literals.ATTRIBUTE;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public Action getAction() {
return AttributeActionHelper.INSTANCE.getAction(this);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void setAction(Action action) {
AttributeActionHelper.INSTANCE.setAction(this, action);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public EAttribute getType() {
if (type != null && type.eIsProxy()) {
InternalEObject oldType = (InternalEObject)type;
type = (EAttribute)eResolveProxy(oldType);
if (type != oldType) {
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.RESOLVE, HenshinPackage.ATTRIBUTE__TYPE, oldType, type));
}
}
return type;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public EAttribute basicGetType() {
return type;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void setType(EAttribute newType) {
EAttribute oldType = type;
type = newType;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, HenshinPackage.ATTRIBUTE__TYPE, oldType, type));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public String getValue() {
return value;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void setValue(String newValue) {
String oldValue = value;
value = newValue;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, HenshinPackage.ATTRIBUTE__VALUE, oldValue, value));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public Node getNode() {
if (eContainerFeatureID() != HenshinPackage.ATTRIBUTE__NODE) return null;
return (Node)eInternalContainer();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public NotificationChain basicSetNode(Node newNode, NotificationChain msgs) {
msgs = eBasicSetContainer((InternalEObject)newNode, HenshinPackage.ATTRIBUTE__NODE, msgs);
return msgs;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void setNode(Node newNode) {
if (newNode != eInternalContainer() || (eContainerFeatureID() != HenshinPackage.ATTRIBUTE__NODE && newNode != null)) {
if (EcoreUtil.isAncestor(this, newNode))
throw new IllegalArgumentException("Recursive containment not allowed for " + toString());
NotificationChain msgs = null;
if (eInternalContainer() != null)
msgs = eBasicRemoveFromContainer(msgs);
if (newNode != null)
msgs = ((InternalEObject)newNode).eInverseAdd(this, HenshinPackage.NODE__ATTRIBUTES, Node.class, msgs);
msgs = basicSetNode(newNode, msgs);
if (msgs != null) msgs.dispatch();
}
else if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, HenshinPackage.ATTRIBUTE__NODE, newNode, newNode));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public Object getConstant() {
return constant;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public boolean isNull() {
return null_;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public Attribute getActionAttribute() {
return ActionElementFinder.getActionElement(this, AttributeActionHelper.INSTANCE);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public Graph getGraph() {
Node node = getNode();
return (node!=null) ? node.getGraph() : null;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
switch (featureID) {
case HenshinPackage.ATTRIBUTE__NODE:
if (eInternalContainer() != null)
msgs = eBasicRemoveFromContainer(msgs);
return basicSetNode((Node)otherEnd, msgs);
}
return super.eInverseAdd(otherEnd, featureID, msgs);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
switch (featureID) {
case HenshinPackage.ATTRIBUTE__NODE:
return basicSetNode(null, msgs);
}
return super.eInverseRemove(otherEnd, featureID, msgs);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) {
switch (eContainerFeatureID()) {
case HenshinPackage.ATTRIBUTE__NODE:
return eInternalContainer().eInverseRemove(this, HenshinPackage.NODE__ATTRIBUTES, Node.class, msgs);
}
return super.eBasicRemoveFromContainerFeature(msgs);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public Object eGet(int featureID, boolean resolve, boolean coreType) {
switch (featureID) {
case HenshinPackage.ATTRIBUTE__ACTION:
return getAction();
case HenshinPackage.ATTRIBUTE__TYPE:
if (resolve) return getType();
return basicGetType();
case HenshinPackage.ATTRIBUTE__VALUE:
return getValue();
case HenshinPackage.ATTRIBUTE__NODE:
return getNode();
case HenshinPackage.ATTRIBUTE__CONSTANT:
return getConstant();
case HenshinPackage.ATTRIBUTE__NULL:
return isNull();
}
return super.eGet(featureID, resolve, coreType);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void eSet(int featureID, Object newValue) {
switch (featureID) {
case HenshinPackage.ATTRIBUTE__ACTION:
setAction((Action)newValue);
return;
case HenshinPackage.ATTRIBUTE__TYPE:
setType((EAttribute)newValue);
return;
case HenshinPackage.ATTRIBUTE__VALUE:
setValue((String)newValue);
return;
case HenshinPackage.ATTRIBUTE__NODE:
setNode((Node)newValue);
return;
}
super.eSet(featureID, newValue);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void eUnset(int featureID) {
switch (featureID) {
case HenshinPackage.ATTRIBUTE__ACTION:
setAction(ACTION_EDEFAULT);
return;
case HenshinPackage.ATTRIBUTE__TYPE:
setType((EAttribute)null);
return;
case HenshinPackage.ATTRIBUTE__VALUE:
setValue(VALUE_EDEFAULT);
return;
case HenshinPackage.ATTRIBUTE__NODE:
setNode((Node)null);
return;
}
super.eUnset(featureID);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public boolean eIsSetGen(int featureID) {
switch (featureID) {
case HenshinPackage.ATTRIBUTE__ACTION:
return ACTION_EDEFAULT == null ? getAction() != null : !ACTION_EDEFAULT.equals(getAction());
case HenshinPackage.ATTRIBUTE__TYPE:
return type != null;
case HenshinPackage.ATTRIBUTE__VALUE:
return VALUE_EDEFAULT == null ? value != null : !VALUE_EDEFAULT.equals(value);
case HenshinPackage.ATTRIBUTE__NODE:
return getNode() != null;
case HenshinPackage.ATTRIBUTE__CONSTANT:
return CONSTANT_EDEFAULT == null ? constant != null : !CONSTANT_EDEFAULT.equals(constant);
case HenshinPackage.ATTRIBUTE__NULL:
return null_ != NULL_EDEFAULT;
}
return super.eIsSet(featureID);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
@Override
public boolean eIsSet(int featureID) {
if (featureID==HenshinPackage.ATTRIBUTE__ACTION) {
return false;
}
return eIsSetGen(featureID);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
if (baseClass == GraphElement.class) {
switch (derivedFeatureID) {
case HenshinPackage.ATTRIBUTE__ACTION: return HenshinPackage.GRAPH_ELEMENT__ACTION;
default: return -1;
}
}
return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
if (baseClass == GraphElement.class) {
switch (baseFeatureID) {
case HenshinPackage.GRAPH_ELEMENT__ACTION: return HenshinPackage.ATTRIBUTE__ACTION;
default: return -1;
}
}
return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
@Override
public String toString() {
String type = (this.type!=null) ? this.type.getName() : null;
return "Attribute (type: " + type + ", value: " + value + ")";
}
} //AttributeImpl